Execute a Loading or Performance Test on ZK using JMeter

From Documentation
DocumentationSmall Talks2012JanuaryExecute a Loading or Performance Test on ZK using JMeter
Execute a Loading or Performance Test on ZK using JMeter

Author
Dennis Chen, Senior Engineer, Potix Corporation
Date
January 27, 2012
Version
ZK 6

Introduction

In this small talk, I am going to talk about how you can execute a loading or performance test on ZK applications using JMeter. It not only shows the load on first request to a ZUL page but also the load on subsequence Ajax request in that page. It is always a difficult part to test an Ajax request because of the uuid that is dynamically created. In this article, I will show you the steps of how;

  • To write a simple IdGenerator
  • Use JMeter to record a request
  • Make JMeter testcase replayable

Implementation Steps

To Write a simple IdGenerator

It is important to write a IdGenerator in order to create a predictable desktop id and a component id when testing, then we can record and replay the testcase.

There are two types of ids that needs to be discussed:

1. desktop id - the concept to create a desktop id is that it must be unique in a session and must be passed to subsequent Ajax requests. The idea to provide a predictable desktop id is really simple - 'Server doesn't decide it, testcase do it'

2. component id - the concept to create a component id is that it is not only unique in a scope, but it is also fixed if the component is a 'replay-able target'. For example, when a button is clicked in the testcase, then, the id of the button must be fixed to be replayed. This really depends on your loading testcase target (whether the page creates dynamic number of components or not).


Here, the following code represents a simple sequence in the desktop since my target page creates fixed sequence/number components

public class SequenceIdGenerator implements IdGenerator{
	public String nextComponentUuid(Desktop desktop, Component comp) {
		String number;
		if ((number = (String)desktop.getAttribute("Id_Num")) == null) {
			number = "0";
			desktop.setAttribute("Id_Num", number);
		}
		int i = Integer.parseInt(number);
		i++;// Start from 1
		desktop.setAttribute("Id_Num", String.valueOf(i));
		return "t_" + i;
	}

	public String nextDesktopId(Desktop desktop) {
		HttpServletRequest req = (HttpServletRequest)Executions.getCurrent().getNativeRequest();
		String dtid = req.getParameter("tdtid");
		if(dtid!=null){
			//System.out.println(" use client dtid "+dtid); to
		}
		return dtid==null?null:dtid;
	}
	public String nextPageUuid(Page page) {
		return null;
	}
}

To use this generator, we have to add a configuration to zk.xml

<system-config>
	<id-generator-class>foo.jmtest.SequenceIdGenerator</id-generator-class>
</system-config>

When an ID generator is introduced to a test environment, the next question is usually how to enable it or disable it depending on the environment. With ZK, it can be done by specifying a library property org.zkoss.zk.config.path

Use JMeter to record a request

Now, I will show you how to RECORD the testcase, please download and install JMeter (version 2.5.1 is used for this article.), then do the following steps;

  1. Create a Thread Group in Test Plan, name it for example 'Test Search'
  2. Add User Defined Variables in Test Search
  3. Add HTTP Cookie Manager in Test Search
  4. Add HTTP Request Defaults in Test Search
  5. Edit HTTP Request Defaults, set the Server Name and Port Number (in this case, localhost and 8080) to the application that configured already by SequenceIdGenerator
  6. Create a HTTP Proxy Server in WorkBench, and edit it as follows
    • Set port to 9090 (or any other port in your control)
    • Set Target to Controller to Test Plan > Test Search
    • Add Include URL Patterns
      • .*/zkau.*
      • .*\.zul
    • Add Exclude URL Patterns
      • .*/zkau/web/.*
  7. Start the HTTP Proxy Server


Now, you are ready to record the request of the browser to a test case. Please switch the proxy of your browser to host:port (in this case, proxy is localhost:9090), and link to the application (in this case, it is http://localhost:8080/jmtest/search.zul) . I did some selection, textbox typing, and button clicking , you will see not only the first zul request was recorded, but also zkau too. After this has been done, switch the proxy off, and we need to tick off a checklist of the record.


  • Check that the uuid of zkau is created by SequenceIdGenerator (it will have prefix t_)
  • Check that there is no rmDesktop command in the zkau record, if you have one, please remove it. (It is for removing previous tasks when we recorded the testcase, we don't need it anymore)
    • Another idea of rmDesktop record from this discussion : thread. You could move this record to the end of records, so after each loop of the test, this desktop will be removed, it is a better solution than set max-desktop to 2.
  • Make sure Server Name and Port Number are recorded in zkau since we already set them in HTTP Request Defaults.


Here are some screenshots

prepare http proxy server
record of zul
record of zkau
record of rmdesktop

Make JMeter testcase Replayable

To make this testcase replayable, we have to assign the desktop id, following are the steps;


  1. Add dtid = 0 to User Defined Variables (remember don't add this before you record the testcase, remove this before you re-record the testcase)
  2. Add dtid Variable
  3. Add a parameter tdtid = ${__intSum(${dtid},1,dtid)} to zul request (in this case, /jmtest/search.zul), tdtid is the parameter that will be checked in SequenceIdGenerator
  4. Add tdtid parameter to zul request
  5. For every zkau request, set the parameter value of dtid to ${dtid} , now the zkau request will send the dtid that we are expecting.
  6. Set dtid in zkau requests

By doing these few steps, we can replay the testcase, but, before that, you have to add some 'Listener and tunning the thread' strategy. To simplify this case , I will just add View Results in Table to Test Search then run the test case. To check whether the testcase is running correctly or not, you can add some logs in you application to see whether or not the action is called.

Example test result
A test result

Other loading test hints

For the loading test to run smoothly, there are some notes I think you should also know.

  • Add a Uniform Random Timer to Test Case (set delay to 500ms - 2000ms) to test case, it makes the loading test like a normal access to your application , not a DOS (Deny of Service).
  • Server will always crash if you allow a lot of threads to ATTACK it without tunning the server. You have to design a test plan to test your application from light loading to stress loading and analysis the limitation.
  • Tune the native server or database configuration if the result is not as expected, there are too many reasons as to why application does not reach expected performance.
  • Depending on the test plan, you had better set the max-desktop of ZK to two in order to reduce the memory consumption on the servers of each test thread

Download

Download the JMeter project file here and the target application here


Comments



Copyright © Potix Corporation. This article is licensed under GNU Free Documentation License.